#include "server.h"
#include <QDateTime>
#include <QUuid>
#include <QPixmap>
#include <QJsonDocument>
#include <QHostInfo>
#include <QDir>
#include <QStandardPaths>
#include <QFileInfo>
#include <QCoreApplication>
#include <QCryptographicHash>
#include <QStorageInfo>
#include <QThread>
#include <QBuffer>
#include <zlib.h>

// 添加static关键字避免链接时的多重定义错误
// 数据解压缩函数
static QByteArray decompressData(const QByteArray &compressedData, int originalSize) {
    if (compressedData.isEmpty() || originalSize <= 0)
        return QByteArray();

    QByteArray decompressed;
    decompressed.resize(originalSize);
    
    uLongf decompressedSize = originalSize;
    
    // 解压缩数据
    int result = uncompress((Bytef*)decompressed.data(), &decompressedSize,
                           (const Bytef*)compressedData.data(), compressedData.size());
    
    if (result != Z_OK) {
        // 解压缩失败
        return QByteArray();
    }
    
    // 调整解压缩后数据的大小
    decompressed.resize(decompressedSize);
    return decompressed;
}

// 添加static关键字避免链接时的多重定义错误
// 数据压缩函数
static QByteArray compressData(const QByteArray &data, int level = Z_BEST_COMPRESSION) {
    if (data.isEmpty())
        return QByteArray();

    // 计算压缩后最大可能的大小
    uLongf compressedSize = compressBound(data.size());
    QByteArray compressed;
    compressed.resize(compressedSize);

    // 压缩数据
    int result = compress2((Bytef*)compressed.data(), &compressedSize, 
                          (const Bytef*)data.data(), data.size(), level);
    
    if (result != Z_OK) {
        // 压缩失败，返回原始数据
        return data;
    }

    // 调整压缩后数据的大小
    compressed.resize(compressedSize);
    return compressed;
}

Server::Server(QObject *parent)
    : QObject(parent),
      tcpServer(nullptr),
      screenCapture(nullptr),
      inputSimulator(nullptr),
      lanService(LANService::getInstance()),
      audioCapture(nullptr),
      running(false),
      serverPort(0),
      remoteControlEnabled(true),
      lanDiscoveryEnabled(false),
      audioEnabled(false),
      audioQuality(2)
{
    tcpServer = new QTcpServer(this);
    screenCapture = new ScreenCapture(this);
    inputSimulator = new InputSimulator(this);
    lanService = LANService::getInstance();
    audioCapture = new AudioCapture(this);
    
    // 设置默认服务器名称为主机名
    serverName = QHostInfo::localHostName();
    
    // 初始化文件接收目录
    // 尝试标准下载路径
    fileReceiveDir = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
    // 备选路径
    if (fileReceiveDir.isEmpty() || !QFileInfo(fileReceiveDir).isWritable()) {
        // 尝试桌面路径
        fileReceiveDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    }
    // 最后备选，用户主目录
    if (fileReceiveDir.isEmpty() || !QFileInfo(fileReceiveDir).isWritable()) {
        fileReceiveDir = QDir::homePath();
    }

    // 输出所有可能的标准路径供参考
    LOG_INFO("标准路径列表：");
    LOG_INFO(QString("文档: %1").arg(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)));
    LOG_INFO(QString("下载: %1").arg(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)));
    LOG_INFO(QString("桌面: %1").arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)));
    LOG_INFO(QString("主目录: %1").arg(QDir::homePath()));

    // 检查目录权限
    QFileInfo dirInfo(fileReceiveDir);
    if (!dirInfo.isWritable()) {
        LOG_ERROR(QString("文件接收目录不可写: %1").arg(fileReceiveDir));
        // 创建备用目录在可执行文件目录下
        fileReceiveDir = QCoreApplication::applicationDirPath() + QDir::separator() + "received_files";
        QDir dir(fileReceiveDir);
        if (!dir.exists()) {
            dir.mkpath(".");
        }
        LOG_INFO(QString("改用备用目录: %1").arg(fileReceiveDir));
    } else {
        LOG_INFO(QString("文件接收目录权限检查通过，目录可写"));
    }

    // 打印最终使用的目录
    LOG_INFO(QString("最终文件接收目录设置为: %1").arg(fileReceiveDir));
    
    // 连接信号
    connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
    
    connect(screenCapture, &ScreenCapture::screenUpdated, this, &Server::onScreenUpdated);
    connect(screenCapture, &ScreenCapture::regionUpdated, this, &Server::onRegionUpdated);
    
    // 连接音频相关信号
    connect(audioCapture, &AudioCapture::audioDataAvailable, this, &Server::onAudioDataAvailable);
    connect(audioCapture, &AudioCapture::errorOccurred, this, &Server::onAudioCaptureError);
    
    // 连接鼠标键盘事件处理
    connect(this, &Server::mouseEventReceived, this, &Server::handleMouseEvent);
    connect(this, &Server::keyboardEventReceived, this, &Server::handleKeyboardEvent);
    
    // 初始化输入模拟器
    if (!inputSimulator->initialize()) {
        LOG_WARNING("输入模拟器初始化失败，远程控制功能可能不可用");
    }
    
    // 设置音频质量
    audioCapture->setQuality(audioQuality);
    
    LOG_INFO("服务器初始化完成");
}

Server::~Server()
{
    stop();
    
    // 停止音频捕获
    audioCapture->stop();
    
    LOG_INFO("服务器已销毁");
}

bool Server::start(quint16 port)
{
    if (running) {
        LOG_WARNING("服务器已经在运行");
        return true;
    }
    
    LOG_INFO(QString("正在启动服务器，监听端口: %1").arg(port));
    
    if (!tcpServer->listen(QHostAddress::Any, port)) {
        LOG_ERROR(QString("无法启动服务器: %1").arg(tcpServer->errorString()));
        return false;
    }
    
    serverPort = port;
    running = true;
    
    // 启动屏幕捕获
    screenCapture->start();
    
    // 如果启用了局域网发现服务，启动它
    if (lanDiscoveryEnabled) {
        startLANDiscovery();
    }
    
    emit serverStatusChanged(true);
    
    LOG_INFO(QString("服务器启动成功，正在监听端口: %1").arg(port));
    
    return true;
}

void Server::stop()
{
    if (!running) {
        return;
    }
    
    LOG_INFO("正在停止服务器");
    
    // 断开所有客户端连接
    for (auto it = clients.begin(); it != clients.end(); ++it) {
        QTcpSocket *clientSocket = it.key();
        stopClientScreenUpdates(clientSocket);
        
        if (clientSocket->state() == QAbstractSocket::ConnectedState) {
            clientSocket->disconnectFromHost();
        }
    }
    
    // 停止局域网发现服务
    if (lanDiscoveryEnabled) {
        stopLANDiscovery();
    }
    
    // 停止屏幕捕获
    screenCapture->stop();
    
    // 停止服务器
    tcpServer->close();
    
    clients.clear();
    clientsById.clear();
    
    running = false;
    emit serverStatusChanged(false);
    
    LOG_INFO("服务器已停止");
}

QStringList Server::getConnectedClients() const
{
    return clientsById.keys();
}

bool Server::disconnectClient(const QString &clientId)
{
    if (!clientsById.contains(clientId)) {
        LOG_WARNING(QString("断开客户端失败: 未找到客户端 %1").arg(clientId));
        return false;
    }
    
    QTcpSocket *socket = clientsById[clientId];
    
    // 停止屏幕更新
    stopClientScreenUpdates(socket);
    
    // 发送断开连接消息
    QJsonObject data;
    data["reason"] = "服务器主动断开";
    sendMessage(socket, MessageType::Disconnect, data);
    
    socket->disconnectFromHost();
    LOG_INFO(QString("已断开客户端连接: %1").arg(clientId));
    
    return true;
}

bool Server::isRunning() const
{
    return running;
}

void Server::setCaptureFrameRate(int fps)
{
    if (fps <= 0 || fps > 60) {
        LOG_WARNING(QString("无效的帧率: %1").arg(fps));
        return;
    }
    
    // 重启屏幕捕获
    screenCapture->stop();
    screenCapture->start(fps);
    
    LOG_INFO(QString("屏幕捕获帧率已设置为: %1 FPS").arg(fps));
}

void Server::setCompressionQuality(int quality)
{
    screenCapture->setCompressionQuality(quality);
}

void Server::setDiffEncodingEnabled(bool enabled)
{
    screenCapture->setDiffEncodingEnabled(enabled);
}

void Server::setRemoteControlEnabled(bool enabled)
{
    remoteControlEnabled = enabled;
    LOG_INFO(QString("远程控制%1").arg(enabled ? "已启用" : "已禁用"));
}

void Server::onNewConnection()
{
    // 处理新的客户端连接
    QTcpSocket *socket = tcpServer->nextPendingConnection();
    
    if (!socket) {
        LOG_ERROR("新的客户端连接但获取socket失败");
        return;
    }
    
    LOG_INFO(QString("新的客户端连接: %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
    
    // 添加客户端信息
    ClientInfo clientInfo;
    clientInfo.socket = socket;
    clientInfo.clientAddress = socket->peerAddress();
    clientInfo.clientPort = socket->peerPort();
    clientInfo.connectTime = QDateTime::currentDateTime();
    clientInfo.receivingScreenUpdates = false;
    clientInfo.screenUpdateTimer = new QTimer(this);
    clientInfo.updateInterval = 100; // 默认100ms更新一次屏幕
    clientInfo.receivingAudioStream = false;
    
    clients[socket] = clientInfo;
    
    // 连接信号槽
    connect(socket, &QTcpSocket::readyRead, this, &Server::onReadyRead);
    connect(socket, &QTcpSocket::disconnected, this, &Server::onClientDisconnected);
    connect(clientInfo.screenUpdateTimer, &QTimer::timeout, this, [this, socket]() {
        this->sendScreenUpdateToClient(socket);
    });
}

void Server::onClientDisconnected()
{
    QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
    if (!socket) {
        return;
    }
    
    // 查找客户端ID
    QString clientId;
    for (auto it = clientsById.begin(); it != clientsById.end(); ++it) {
        if (it.value() == socket) {
            clientId = it.key();
            break;
        }
    }
    
    LOG_INFO(QString("客户端断开连接: %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
    
    // 停止屏幕更新
    if (clients.contains(socket)) {
        stopClientScreenUpdates(socket);
        stopClientAudioStream(socket);
        
        // 释放客户端资源
        ClientInfo &clientInfo = clients[socket];
        delete clientInfo.screenUpdateTimer;
        
        // 从映射中移除
        clients.remove(socket);
    }
    
    // 清理文件传输状态
    if (fileReceiveMap.contains(socket)) {
        FileReceiveContext &context = fileReceiveMap[socket];
        if (context.file && context.file->isOpen()) {
            context.file->close();
        }
        fileReceiveMap.remove(socket);
    }
    
    // 如果找到了客户端ID，从映射中移除
    if (!clientId.isEmpty()) {
        clientsById.remove(clientId);
        emit clientDisconnected(clientId);
    }
    
    // 清理socket
    socket->deleteLater();
}

void Server::onReadyRead()
{
    QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
    
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    QByteArray data = socket->readAll();
    processClientMessage(socket, data);
}

void Server::onScreenUpdated(const QByteArray &imageData, const QSize &size)
{
    // 屏幕数据更新，不需要立即处理
    // 每个客户端有自己的定时器来请求屏幕数据
    Q_UNUSED(imageData);
    Q_UNUSED(size);
}

void Server::onRegionUpdated(const QVector<ScreenRegion> &regions, const QSize &size)
{
    // 区域数据更新，不需要立即处理
    // 每个客户端有自己的定时器来请求屏幕数据
    Q_UNUSED(regions);
    Q_UNUSED(size);
}

void Server::sendScreenUpdateToClient(QTcpSocket *socket)
{
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    // 检查客户端是否应该接收屏幕更新
    if (!clients[socket].receivingScreenUpdates) {
        return;
    }
    
    // 检查客户端是否正在传输文件，如果是则跳过屏幕更新以提高文件传输速度
    if (fileReceiveMap.contains(socket)) {
        LOG_INFO("客户端正在传输文件，暂停屏幕更新");
        return;
    }
    
    // 捕获整个屏幕
    QByteArray imageData;
    if (screenCapture->isDiffEncodingEnabled()) {
        // 使用差分编码时，发送整个屏幕（后续可以优化为只发送变化区域）
        imageData = screenCapture->captureFullScreen();
    } else {
        // 不使用差分编码，直接捕获整个屏幕
        imageData = screenCapture->captureFullScreen();
    }
    
    if (imageData.isEmpty()) {
        LOG_WARNING("捕获屏幕失败，跳过此次更新");
        return;
    }
    
    // 压缩屏幕数据
    QByteArray compressedData = compressData(imageData);
    bool isCompressed = (compressedData.size() < imageData.size());
    QByteArray dataToSend = isCompressed ? compressedData : imageData;
    
    // 记录压缩率
    double compressionRatio = isCompressed ? 
        (100.0 - (compressedData.size() * 100.0 / imageData.size())) : 0.0;
    
    LOG_INFO(QString("屏幕数据: 原始大小=%1KB, 压缩后=%2KB, 压缩率=%3%")
            .arg(imageData.size() / 1024.0, 0, 'f', 1)
            .arg(dataToSend.size() / 1024.0, 0, 'f', 1)
            .arg(compressionRatio, 0, 'f', 1));
    
    QJsonObject data;
    data["imageData"] = QString(dataToSend.toBase64());
    data["compressed"] = isCompressed;
    data["originalSize"] = imageData.size();
    
    // 获取屏幕分辨率
    QSize screenSize = screenCapture->getScreenSize();
    
    data["width"] = screenSize.width();
    data["height"] = screenSize.height();
    data["timestamp"] = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    
    sendMessage(socket, MessageType::ScreenData, data);
}

QString Server::generateClientId(QTcpSocket *socket)
{
    QString address = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    QString timestamp = QString::number(QDateTime::currentDateTime().toSecsSinceEpoch());
    
    // 生成唯一ID
    QString uniqueString = QString("%1:%2:%3").arg(address).arg(port).arg(timestamp);
    return QUuid::createUuidV5(QUuid::createUuid(), uniqueString).toString().remove("{").remove("}");
}

void Server::processClientMessage(QTcpSocket *socket, const QByteArray &data)
{
    // 每个客户端保持各自的数据缓冲区
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    // 追加到客户端的接收缓冲区
    ClientInfo &clientInfo = clients[socket];
    clientInfo.receiveBuffer.append(data);
    
    // 循环处理所有完整的数据包
    int startPos = 0;
    while ((startPos = clientInfo.receiveBuffer.indexOf("HH_START", startPos)) != -1) {
        int endPos = clientInfo.receiveBuffer.indexOf("HH_END", startPos);
        
        if (endPos == -1) {
            // 没有找到包尾，数据包不完整，等待更多数据
            break;
        }
        
        // 提取JSON数据部分
        QByteArray jsonData = clientInfo.receiveBuffer.mid(startPos + 8, endPos - startPos - 8);
        
        QJsonParseError parseError;
        QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
        
        if (parseError.error != QJsonParseError::NoError) {
            LOG_ERROR(QString("JSON解析错误: %1").arg(parseError.errorString()));
            // 跳过此数据包，继续处理后面的
            startPos = endPos + 7; // "HH_END"的长度是7
            continue;
        }
        
        QJsonObject message = doc.object();
        
        if (!message.contains("type") || !message.contains("data")) {
            LOG_WARNING("收到格式错误的消息");
            // 跳过此数据包，继续处理后面的
            startPos = endPos + 7;
            continue;
        }
        
        QString typeStr = message["type"].toString();
        QJsonObject dataObj = message["data"].toObject();
        
        // 获取客户端ID
        QString clientId = dataObj.contains("clientId") ? dataObj["clientId"].toString() : generateClientId(socket);
        
        LOG_INFO(QString("从客户端 [%1] 收到 %2 类型消息").arg(clientId).arg(typeStr));
        
        // 处理消息
        if (typeStr == "Connect") {
            // 处理连接请求
            QString clientAddress = socket->peerAddress().toString();
            quint16 clientPort = socket->peerPort();
            
            QString clientId = generateClientId(socket);
            
            // 更新客户端信息
            ClientInfo &clientInfo = clients[socket];
            clientInfo.clientAddress = socket->peerAddress();
            clientInfo.clientPort = clientPort;
            clientInfo.connectTime = QDateTime::currentDateTime();
            
            // 保存客户端ID到映射
            clientsById[clientId] = socket;
            
            LOG_INFO(QString("新客户端连接请求: %1 (%2:%3)").arg(clientId).arg(clientAddress).arg(clientPort));
            
            // 发送连接响应
            QJsonObject response;
            response["message"] = "连接成功";
            response["clientId"] = clientId;
            
            sendMessage(socket, MessageType::Connect, response);
            
            // 直接授权客户端
            QString username = QString("Guest-%1").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss"));
            authorizeClient(socket, username);
            
            // 触发客户端连接信号
            emit clientConnected(clientId, clientAddress);
        }
        else if (typeStr == "Authenticate") {
            // 认证请求，现在直接授权
            QString username = dataObj["username"].toString();
            authorizeClient(socket, username);
        }
        else if (typeStr == "ScreenData") {
            // 请求屏幕数据
            bool fullScreen = dataObj["fullscreen"].toBool();
            
            // 如果客户端想开始或停止连续获取屏幕数据
            if (dataObj.contains("continuous")) {
                bool continuous = dataObj["continuous"].toBool();
                int fps = dataObj.contains("fps") ? dataObj["fps"].toInt() : 10;
                
                if (continuous) {
                    // 开始连续发送屏幕更新
                    startClientScreenUpdates(socket, fps);
                } else {
                    // 停止连续发送屏幕更新
                    stopClientScreenUpdates(socket);
                }
            } else {
                // 只发送一次屏幕数据
                sendScreenData(socket, fullScreen);
            }
        }
        else if (typeStr == "MouseEvent") {
            // 鼠标事件
            int x = dataObj["x"].toInt();
            int y = dataObj["y"].toInt();
            int button = dataObj["button"].toInt();
            bool pressed = dataObj["pressed"].toBool();
            
            // 检查是否是鼠标移动事件（通常button为0）
            // 当button为0且pressed为false时为移动事件，直接调用inputSimulator->moveMouse
            if (button == 0 && !pressed) {
                // 直接处理鼠标移动，不发送信号
                inputSimulator->moveMouse(x, y);
            } else {
                // 按下或释放按钮的事件，发送信号
                emit mouseEventReceived(clientId, x, y, button, pressed);
            }
        }
        else if (typeStr == "KeyboardEvent") {
            // 处理键盘事件
            int key = dataObj["key"].toInt();
            bool pressed = dataObj["pressed"].toBool();
            
            LOG_INFO(QString("收到键盘事件: 客户端=%1, 键值=%2, %3")
                    .arg(clientId)
                    .arg(key)
                    .arg(pressed ? "按下" : "释放"));
            
            // 在此处直接处理键盘事件，避免信号-槽可能导致的延迟
            if (remoteControlEnabled) {
                // 直接调用处理函数
                handleKeyboardEvent(clientId, key, pressed);
            } else {
                LOG_WARNING("远程控制已禁用，键盘事件被忽略");
                // 向客户端发送提示信息
                QJsonObject errorObj;
                errorObj["message"] = "远程控制已禁用，键盘事件被忽略";
                sendMessage(socket, MessageType::Error, errorObj);
            }
            
            // 同时发送信号，供其他组件使用
            emit keyboardEventReceived(clientId, key, pressed);
        }
        else if (typeStr == "AudioData") {
            // 处理音频命令
            QString action = dataObj["action"].toString();
            
            if (action == "start") {
                // 客户端请求开始音频流
                startClientAudioStream(socket);
            }
            else if (action == "stop") {
                // 客户端请求停止音频流
                stopClientAudioStream(socket);
            }
            else {
                LOG_WARNING(QString("未知的音频命令: %1").arg(action));
            }
        }
        else if (typeStr == "Disconnect") {
            // 断开连接请求
            QString reason = dataObj["reason"].toString();
            LOG_INFO(QString("客户端请求断开连接: %1，原因: %2").arg(clientId).arg(reason));
            stopClientScreenUpdates(socket);
            stopClientAudioStream(socket);
            socket->disconnectFromHost();
        }
        // 文件传输相关消息
        else if (typeStr == "FileSendRequest") {
            // 文件传输请求
            LOG_INFO("收到文件传输请求");
            LOG_INFO(QString("完整消息内容: %1").arg(QString(jsonData)));
            handleFileSendRequest(socket, dataObj);
        }
        else if (typeStr == "FileSendData") {
            // 文件数据块
            LOG_INFO("收到文件数据块");
            handleFileSendData(socket, dataObj);
        }
        else if (typeStr == "FileSendFinish") {
            // 文件传输完成
            LOG_INFO("收到文件传输完成消息");
            handleFileSendFinish(socket, dataObj);
        }
        else if (typeStr == "FileSendAck") {
            // 文件数据块确认
            LOG_INFO("收到文件数据块确认消息");
            // 这是客户端确认消息，服务端不需要特殊处理
            // 只记录日志，保持透明性
            if (dataObj.contains("blockNumber")) {
                int blockNumber = dataObj["blockNumber"].toInt();
                bool success = dataObj.contains("success") ? dataObj["success"].toBool() : false;
                LOG_INFO(QString("客户端确认数据块 #%1 %2")
                        .arg(blockNumber)
                        .arg(success ? "成功" : "失败"));
            }
        }
        else {
            LOG_WARNING(QString("未处理的消息类型: %1").arg(typeStr));
        }
        
        // 处理完这个数据包，从缓冲区中移除
        clientInfo.receiveBuffer.remove(0, endPos + 7);
        
        // 重置起始位置，从缓冲区开头继续查找
        startPos = 0;
    }
    
    // 如果缓冲区过大（例如超过1MB），可能存在问题，清空缓冲区
    if (clientInfo.receiveBuffer.size() > 1024 * 1024) {
        LOG_WARNING("客户端接收缓冲区过大，清空缓冲区");
        clientInfo.receiveBuffer.clear();
    }
}

void Server::authorizeClient(QTcpSocket *socket, const QString &username)
{
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    // 更新客户端信息
    ClientInfo &clientInfo = clients[socket];
    clientInfo.username = username.isEmpty() ? 
        QString("Guest-%1").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss")) : 
        username;
    
    QJsonObject response;
    response["success"] = true;
    response["message"] = "已授权";
    
    LOG_INFO(QString("客户端授权成功: %1").arg(clientInfo.username));
    
    sendMessage(socket, MessageType::Authenticate, response);
    
    // 自动开始屏幕更新
    startClientScreenUpdates(socket, 10);
}

void Server::startClientScreenUpdates(QTcpSocket *socket, int fps)
{
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    ClientInfo &clientInfo = clients[socket];
    
    // 先停止现有的更新
    if (clientInfo.receivingScreenUpdates) {
        stopClientScreenUpdates(socket);
    }
    
    // 设置更新间隔
    clientInfo.updateInterval = 1000 / fps;
    clientInfo.receivingScreenUpdates = true;
    
    // 启动定时器
    clientInfo.screenUpdateTimer->start(clientInfo.updateInterval);
    
    LOG_INFO(QString("客户端开始接收屏幕更新, FPS: %1").arg(fps));
}

void Server::stopClientScreenUpdates(QTcpSocket *socket)
{
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    ClientInfo &clientInfo = clients[socket];
    
    if (clientInfo.receivingScreenUpdates) {
        clientInfo.screenUpdateTimer->stop();
        clientInfo.receivingScreenUpdates = false;
        
        LOG_INFO("客户端停止接收屏幕更新");
    }
}

void Server::handleMouseEvent(const QString &clientId, int x, int y, int button, bool pressed)
{
    if (!remoteControlEnabled) {
        LOG_WARNING("收到鼠标事件，但远程控制已禁用");
        return;
    }
    
    LOG_INFO(QString("处理鼠标事件: 客户端=%1, 位置=(%2,%3), 按钮=%4, %5")
             .arg(clientId)
             .arg(x).arg(y)
             .arg(button)
             .arg(pressed ? "按下" : "释放"));
    
    // 模拟鼠标事件
    bool success = false;
    if (pressed) {
        success = inputSimulator->mousePress(x, y, button);
    } else {
        success = inputSimulator->mouseRelease(x, y, button);
    }
    
    if (!success) {
        LOG_ERROR(QString("模拟鼠标事件失败: 位置=(%1,%2), 按钮=%3, %4")
                 .arg(x).arg(y)
                 .arg(button)
                 .arg(pressed ? "按下" : "释放"));
    } else {
        LOG_INFO(QString("成功模拟鼠标事件: 位置=(%1,%2), 按钮=%3, %4")
                .arg(x).arg(y)
                .arg(button)
                .arg(pressed ? "按下" : "释放"));
    }
}

void Server::handleKeyboardEvent(const QString &clientId, int key, bool pressed)
{
    if (!remoteControlEnabled) {
        LOG_WARNING("收到键盘事件，但远程控制已禁用");
        return;
    }
    
    LOG_INFO(QString("处理键盘事件: 客户端=%1, 键值=%2, %3")
             .arg(clientId)
             .arg(key)
             .arg(pressed ? "按下" : "释放"));
    
    // 检查键值是否合法
    if (key <= 0) {
        LOG_ERROR(QString("无效的键值: %1").arg(key));
        return;
    }
    
    // 模拟键盘事件
    bool success = false;
    int retryCount = 0;
    const int maxRetries = 2; // 最多尝试3次（1次初始 + 2次重试）
    
    // 记录键值的映射结果
    int systemKey = inputSimulator->mapKey(key);
    if (systemKey == 0) {
        LOG_ERROR(QString("键值映射失败: Qt键值=%1").arg(key));
        return;
    } else {
        LOG_INFO(QString("键值映射成功: Qt键值=%1 -> 系统键值=%2").arg(key).arg(systemKey));
    }
    
    while (!success && retryCount <= maxRetries) {
        if (pressed) {
            success = inputSimulator->keyPress(key);
        } else {
            success = inputSimulator->keyRelease(key);
        }
        
        if (!success) {
            LOG_WARNING(QString("模拟键盘事件失败: 键值=%1, %2, 尝试=%3/%4")
                     .arg(key)
                     .arg(pressed ? "按下" : "释放")
                     .arg(retryCount + 1)
                     .arg(maxRetries + 1));
            retryCount++;
            
            // 短暂等待后重试
            QThread::msleep(50);
        } else {
            LOG_INFO(QString("成功模拟键盘事件: 键值=%1, %2%3")
                    .arg(key)
                    .arg(pressed ? "按下" : "释放")
                    .arg(retryCount > 0 ? QString(", 尝试=%1次").arg(retryCount + 1) : ""));
            break;
        }
    }
    
    if (!success) {
        LOG_ERROR(QString("多次尝试模拟键盘事件均失败: 键值=%1, %2")
                 .arg(key)
                 .arg(pressed ? "按下" : "释放"));
    }
}

void Server::setServerName(const QString &name)
{
    serverName = name;
    
    // 如果启用了局域网发现服务并且正在运行，重启它以更新名称
    if (lanDiscoveryEnabled && running) {
        stopLANDiscovery();
        startLANDiscovery();
    }
}

QString Server::getServerName() const
{
    return serverName;
}

void Server::enableLANDiscovery(bool enable)
{
    if (lanDiscoveryEnabled == enable) {
        return;
    }
    
    lanDiscoveryEnabled = enable;
    
    if (running) {
        if (enable) {
            startLANDiscovery();
        } else {
            stopLANDiscovery();
        }
    }
}

bool Server::isLANDiscoveryEnabled() const
{
    return lanDiscoveryEnabled;
}

void Server::startLANDiscovery()
{
    if (!lanService->startServerBroadcast(serverPort, serverName)) {
        LOG_ERROR("无法启动局域网发现服务");
    } else {
        LOG_INFO("局域网发现服务已启动");
    }
}

void Server::stopLANDiscovery()
{
    lanService->stopServerBroadcast();
    LOG_INFO("局域网发现服务已停止");
}

void Server::sendScreenData(QTcpSocket *socket, bool fullScreen)
{
    if (!socket) {
        return;
    }
    
    QByteArray screenData;
    if (fullScreen) {
        screenData = screenCapture->captureFullScreen();
    } else {
        // 只捕获中心区域作为示例
        QSize screenSize = screenCapture->getScreenSize();
        int centerX = screenSize.width() / 4;
        int centerY = screenSize.height() / 4;
        int width = screenSize.width() / 2;
        int height = screenSize.height() / 2;
        
        QRect centerRect(centerX, centerY, width, height);
        screenData = screenCapture->captureRegion(centerRect);
    }
    
    QJsonObject data;
    data["imageData"] = QString(screenData.toBase64());
    
    // 获取屏幕分辨率
    QSize screenSize = screenCapture->getScreenSize();
    
    data["width"] = screenSize.width();
    data["height"] = screenSize.height();
    data["timestamp"] = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    
    sendMessage(socket, MessageType::ScreenData, data);
}

bool Server::sendMessage(QTcpSocket *socket, MessageType type, const QJsonObject &data)
{
    if (!socket) {
        LOG_ERROR("发送消息失败: 无效的socket");
        return false;
    }
    
    // 创建消息
    QJsonObject message;
    
    switch (type) {
    case MessageType::Connect:
        message["type"] = "Connect";
        break;
    case MessageType::Authenticate:
        message["type"] = "Authenticate";
        break;
    case MessageType::ScreenData:
        message["type"] = "ScreenData";
        break;
    case MessageType::MouseEvent:
        message["type"] = "MouseEvent";
        break;
    case MessageType::KeyboardEvent:
        message["type"] = "KeyboardEvent";
        break;
    case MessageType::AudioData:
        message["type"] = "AudioData";
        break;
    case MessageType::AudioFormat:
        message["type"] = "AudioFormat";
        break;
    case MessageType::SystemInfo:
        message["type"] = "SystemInfo";
        break;
    case MessageType::Disconnect:
        message["type"] = "Disconnect";
        break;
    case MessageType::Heartbeat:
        message["type"] = "Heartbeat";
        break;
    case MessageType::Error:
        message["type"] = "Error";
        break;
    case MessageType::FileSendRequest:
        message["type"] = "FileSendRequest";
        break;
    case MessageType::FileSendData:
        message["type"] = "FileSendData";
        break;
    case MessageType::FileSendFinish:
        message["type"] = "FileSendFinish";
        break;
    case MessageType::FileSendAck:
        message["type"] = "FileSendAck";
        break;
    default:
        message["type"] = "Unknown";
        break;
    }
    
    message["data"] = data;
    
    // 转换为JSON
    QJsonDocument doc(message);
    QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
    
    // 添加包头和包尾
    QByteArray packet;
    packet.append("HH_START");  // 包头标识
    packet.append(jsonData);
    packet.append("HH_END");    // 包尾标识
    
    // 发送数据
    qint64 bytesSent = socket->write(packet);
    if (bytesSent != packet.size()) {
        LOG_ERROR("发送数据不完整");
        return false;
    }
    
    return true;
}

void Server::setAudioQuality(int quality)
{
    if (quality < 0 || quality > 5) {
        LOG_WARNING(QString("无效的音频质量: %1，有效范围为0-5").arg(quality));
        return;
    }
    
    audioQuality = quality;
    audioCapture->setQuality(quality);
    
    LOG_INFO(QString("音频质量已设置为: %1").arg(quality));
}

int Server::getAudioQuality() const
{
    return audioQuality;
}

void Server::setAudioEnabled(bool enabled)
{
    if (audioEnabled == enabled) {
        return;
    }
    
    audioEnabled = enabled;
    
    if (enabled) {
        audioCapture->start();
        LOG_INFO("音频传输已启用");
    } else {
        audioCapture->stop();
        LOG_INFO("音频传输已禁用");
    }
}

bool Server::isAudioEnabled() const
{
    return audioEnabled;
}

void Server::onAudioDataAvailable(const QByteArray &data)
{
    if (!audioEnabled || !running) {
        return;
    }
    
    // 向所有接收音频的客户端发送音频数据
    sendAudioDataToClients(data);
}

void Server::onAudioCaptureError(const QString &errorMsg)
{
    LOG_ERROR(QString("音频捕获错误: %1").arg(errorMsg));
    emit errorOccurred(QString("音频捕获错误: %1").arg(errorMsg));
    
    // 可能需要禁用音频功能
    if (audioEnabled) {
        setAudioEnabled(false);
    }
}

void Server::startClientAudioStream(QTcpSocket *socket)
{
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    ClientInfo &clientInfo = clients[socket];
    
    // 如果已经在接收，则不需要重新开始
    if (clientInfo.receivingAudioStream) {
        return;
    }
    
    // 设置客户端为接收音频流状态
    clientInfo.receivingAudioStream = true;
    
    // 查找客户端ID
    QString clientId;
    for (auto it = clientsById.begin(); it != clientsById.end(); ++it) {
        if (it.value() == socket) {
            clientId = it.key();
            break;
        }
    }
    
    LOG_INFO(QString("客户端 [%1] 开始接收音频流").arg(clientId));
    
    // 发送音频格式信息
    QJsonObject audioFormatData;
    audioFormatData["sampleRate"] = audioCapture->getSampleRate();
    audioFormatData["channelCount"] = audioCapture->getChannelCount();
    audioFormatData["sampleSize"] = 16; // 固定为16位
    
    sendMessage(socket, MessageType::AudioFormat, audioFormatData);
    
    // 如果只有一个客户端刚开始接收音频，启动音频捕获
    if (!audioCapture->isCapturing()) {
        setAudioEnabled(true);
    }
}

void Server::stopClientAudioStream(QTcpSocket *socket)
{
    if (!socket || !clients.contains(socket)) {
        return;
    }
    
    ClientInfo &clientInfo = clients[socket];
    
    // 如果不在接收状态，则不需要操作
    if (!clientInfo.receivingAudioStream) {
        return;
    }
    
    // 设置客户端为不接收音频流状态
    clientInfo.receivingAudioStream = false;
    
    // 查找客户端ID
    QString clientId;
    for (auto it = clientsById.begin(); it != clientsById.end(); ++it) {
        if (it.value() == socket) {
            clientId = it.key();
            break;
        }
    }
    
    LOG_INFO(QString("客户端 [%1] 停止接收音频流").arg(clientId));
    
    // 检查是否还有其他客户端在接收音频
    bool anyClientReceivingAudio = false;
    for (auto it = clients.begin(); it != clients.end(); ++it) {
        if (it.value().receivingAudioStream) {
            anyClientReceivingAudio = true;
            break;
        }
    }
    
    // 如果没有客户端接收音频，停止音频捕获
    if (!anyClientReceivingAudio) {
        setAudioEnabled(false);
    }
}

void Server::sendAudioDataToClients(const QByteArray &data)
{
    if (data.isEmpty()) {
        return;
    }
    
    // 统计接收音频的客户端数量
    int clientCount = 0;
    
    // 发送音频数据给所有接收音频的客户端
    for (auto it = clients.begin(); it != clients.end(); ++it) {
        if (it.value().receivingAudioStream) {
            QJsonObject audioData;
            audioData["data"] = QString(data.toBase64());
            
            if (!sendMessage(it.key(), MessageType::AudioData, audioData)) {
                // 查找客户端ID
                QString clientId;
                for (auto idIt = clientsById.begin(); idIt != clientsById.end(); ++idIt) {
                    if (idIt.value() == it.key()) {
                        clientId = idIt.key();
                        break;
                    }
                }
                
                LOG_WARNING(QString("向客户端 [%1] 发送音频数据失败").arg(clientId));
                
                // 标记为不再接收音频
                it.value().receivingAudioStream = false;
            } else {
                clientCount++;
            }
        }
    }
    
    // 如果没有客户端接收音频，停止音频捕获
    if (clientCount == 0 && audioCapture->isCapturing()) {
        setAudioEnabled(false);
    }
}

void Server::handleFileSendRequest(QTcpSocket *socket, const QJsonObject &data)
{
    if (!socket || !clients.contains(socket)) {
        LOG_ERROR("处理文件传输请求失败: 无效的socket或客户端");
        return;
    }
    
    QString fileName = data["fileName"].toString();
    qint64 fileSize = data["fileSize"].toString().toLongLong();
    
    LOG_INFO(QString("收到文件传输请求: 文件名=%1, 大小=%2字节").arg(fileName).arg(fileSize));
    
    // 获取传输ID
    QString transferId;
    if (data.contains("transferId")) {
        transferId = data["transferId"].toString();
    } else if (data.contains("clientId")) {
        transferId = data["clientId"].toString();
    } else {
        transferId = generateClientId(socket);
    }
    
    LOG_INFO(QString("文件传输ID: %1").arg(transferId));
    
    // 暂停该客户端的屏幕更新，提高文件传输速度
    if (clients.contains(socket) && clients[socket].receivingScreenUpdates) {
        LOG_INFO("暂时停止客户端的屏幕更新，以提高文件传输速度");
        stopClientScreenUpdates(socket);
    }
    
    // 文件名安全处理，避免路径遍历漏洞
    fileName = QFileInfo(fileName).fileName();
    
    // 创建带时间戳的文件名，避免重名
    QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
    QString finalFileName = timestamp + "_" + fileName;
    
    // 保证目录后面有分隔符
    if (!fileReceiveDir.endsWith(QDir::separator())) {
        fileReceiveDir += QDir::separator();
    }
    
    QString filePath = fileReceiveDir + finalFileName;
    
    LOG_INFO(QString("准备保存文件: %1").arg(filePath));
    
    // 再次检查目录
    QDir dir(fileReceiveDir);
    if (!dir.exists()) {
        LOG_INFO(QString("接收目录不存在，尝试创建: %1").arg(fileReceiveDir));
        if (!dir.mkpath(".")) {
            LOG_ERROR(QString("无法创建接收目录: %1").arg(fileReceiveDir));
            // 发送错误
            QJsonObject errorObj;
            errorObj["message"] = "服务器无法创建接收目录";
            sendMessage(socket, MessageType::Error, errorObj);
            return;
        }
        LOG_INFO("接收目录创建成功");
    }
    
    LOG_INFO(QString("准备接收文件，完整保存路径: %1").arg(filePath));
    
    // 在map中创建上下文对象
    auto &context = fileReceiveMap[socket];
    context.fileName = finalFileName;
    context.filePath = filePath;
    context.fileSize = fileSize;
    context.receivedSize = 0;
    context.startTime = QDateTime::currentDateTime();
    context.transferId = transferId;
    context.lastBlockNumber = -1;
    
    // 创建新文件
    context.file = new QFile(filePath);
    bool opened = context.file->open(QIODevice::WriteOnly);
    
    if (!opened) {
        LOG_ERROR(QString("无法创建文件: %1, 错误: %2").arg(filePath).arg(context.file->errorString()));
        
        // 尝试在临时目录创建
        QString tempPath = QDir::tempPath() + QDir::separator() + finalFileName;
        LOG_INFO(QString("尝试在临时目录创建文件: %1").arg(tempPath));
        
        delete context.file;
        context.file = new QFile(tempPath);
        context.filePath = tempPath;
        
        opened = context.file->open(QIODevice::WriteOnly);
        if (!opened) {
            LOG_ERROR(QString("无法在临时目录创建文件: %1, 错误: %2").arg(tempPath).arg(context.file->errorString()));
            
            // 发送错误消息回客户端
            QJsonObject errorData;
            errorData["message"] = QString("服务器无法创建文件");
            errorData["transferId"] = transferId;
            sendMessage(socket, MessageType::Error, errorData);
            fileReceiveMap.remove(socket);
            return;
        }
        LOG_INFO("在临时目录创建文件成功");
    }
    
    // 创建接收文件的服务器响应
    QJsonObject response;
    response["message"] = "服务器准备好接收文件";
    response["path"] = filePath;
    response["transferId"] = transferId;
    response["clientId"] = transferId;
    response["status"] = "ready";
    
    LOG_INFO("发送接收文件确认消息");
    
    // 多次尝试发送确认消息，确保客户端能收到
    bool confirmSent = false;
    for (int attempt = 1; attempt <= 3; attempt++) {
        if (sendMessage(socket, MessageType::FileSendRequest, response)) {
            LOG_INFO(QString("发送接收确认消息成功 (尝试 %1/3)").arg(attempt));
            confirmSent = true;
            
            // 成功发送后短暂等待，确保客户端有时间处理
            QThread::msleep(200);
            
            // 再次发送相同的确认消息，增加客户端接收到的可能性
            sendMessage(socket, MessageType::FileSendRequest, response);
            break;
        } else {
            LOG_ERROR(QString("发送接收确认消息失败 (尝试 %1/3)").arg(attempt));
            QThread::msleep(500); // 等待一下再重试
        }
    }
    
    if (!confirmSent) {
        LOG_ERROR("多次尝试发送确认消息均失败，取消文件接收");
        
        // 清理资源
        if (context.file) {
            context.file->close();
            delete context.file;
        }
        fileReceiveMap.remove(socket);
    }
}

void Server::handleFileSendData(QTcpSocket *socket, const QJsonObject &data)
{
    if (!socket || !fileReceiveMap.contains(socket)) {
        LOG_ERROR("处理文件数据失败: 无效的socket或未找到对应的文件接收上下文");
        return;
    }
    
    FileReceiveContext &context = fileReceiveMap[socket];
    if (!context.file || !context.file->isOpen()) {
        LOG_ERROR("文件未打开，无法写入数据");
        
        // 尝试重新打开文件
        if (context.file) {
            delete context.file;
        }
        
        context.file = new QFile(context.filePath);
        if (!context.file->open(QIODevice::ReadWrite)) {
            LOG_ERROR(QString("重新打开文件失败: %1").arg(context.file->errorString()));
            return;
        } else {
            LOG_INFO("成功重新打开文件");
        }
    }
    
    // 获取块编号和偏移量
    int blockNumber = data.contains("blockNumber") ? data["blockNumber"].toInt() : -1;
    qint64 offset = data.contains("offset") ? data["offset"].toVariant().toLongLong() : -1;
    int blockSize = data.contains("blockSize") ? data["blockSize"].toInt() : -1;
    int totalBlocks = data.contains("totalBlocks") ? data["totalBlocks"].toInt() : -1;
    
    // 获取传输ID并验证
    QString transferId = data.contains("transferId") ? data["transferId"].toString() : 
                        data.contains("clientId") ? data["clientId"].toString() : "";
    
    if (!transferId.isEmpty() && transferId != context.transferId) {
        LOG_WARNING(QString("传输ID不匹配: 期望=%1，收到=%2").arg(context.transferId).arg(transferId));
        // 尽管ID不匹配，仍继续处理，可能是重新连接的客户端
    }
    
    LOG_INFO(QString("处理数据块 #%1/%2, 偏移量: %3, 大小: %4字节")
            .arg(blockNumber)
            .arg(totalBlocks)
            .arg(offset)
            .arg(blockSize));
    
    // 检查是否已经接收过这个块
    if (context.receivedBlocks.contains(blockNumber)) {
        LOG_INFO(QString("数据块 #%1 已经接收过，直接确认").arg(blockNumber));
        
        // 发送确认消息
        QJsonObject ackObj;
        ackObj["transferId"] = transferId;
        ackObj["blockNumber"] = blockNumber;
        ackObj["success"] = true;
        ackObj["message"] = "已接收";
        
        // 多次尝试发送确认，确保客户端收到
        for (int attempt = 1; attempt <= 2; attempt++) {
            if (sendMessage(socket, MessageType::FileSendAck, ackObj)) {
                LOG_INFO(QString("发送数据块确认消息成功 (尝试 %1/2)").arg(attempt));
                break;
            } else {
                LOG_WARNING(QString("发送数据块确认消息失败，尝试 %1/2").arg(attempt));
                QThread::msleep(100);
            }
        }
        return;
    }
    
    // 检查块编号是否有效
    if (blockNumber < 0 || (totalBlocks > 0 && blockNumber >= totalBlocks)) {
        LOG_ERROR(QString("无效的数据块编号: %1, 总块数: %2").arg(blockNumber).arg(totalBlocks));
        
        // 发送失败确认消息
        QJsonObject ackObj;
        ackObj["transferId"] = transferId;
        ackObj["blockNumber"] = blockNumber;
        ackObj["success"] = false;
        ackObj["message"] = "无效的数据块编号";
        
        sendMessage(socket, MessageType::FileSendAck, ackObj);
        return;
    }
    
    // 检查块编号是否连续，但不强制要求 - 记录一下即可
    if (blockNumber > 0 && context.lastBlockNumber >= 0 && blockNumber != context.lastBlockNumber + 1) {
        LOG_WARNING(QString("数据块编号不连续: 上一个=%1, 当前=%2").arg(context.lastBlockNumber).arg(blockNumber));
    }
    
    // 解码数据
    QByteArray blockData = QByteArray::fromBase64(data["data"].toString().toLatin1());
    
    // 如果数据已压缩，则解压缩
    bool isCompressed = data.contains("compressed") ? data["compressed"].toBool() : false;
    int originalSize = data.contains("blockSize") ? data["blockSize"].toInt() : blockData.size();
    int compressedSize = data.contains("compressedSize") ? data["compressedSize"].toInt() : blockData.size();
    
    if (isCompressed && originalSize > compressedSize) {
        QByteArray decompressed = decompressData(blockData, originalSize);
        if (!decompressed.isEmpty()) {
            LOG_INFO(QString("数据块 #%1 解压缩成功: %2字节 -> %3字节 (压缩率: %4%)")
                    .arg(blockNumber)
                    .arg(blockData.size())
                    .arg(decompressed.size())
                    .arg(100.0 - (blockData.size() * 100.0 / decompressed.size()), 0, 'f', 1));
            blockData = decompressed;
        } else {
            LOG_ERROR(QString("数据块 #%1 解压缩失败，使用原始数据").arg(blockNumber));
        }
    }
    
    // 验证数据块校验和
    bool checksumValid = true;
    if (data.contains("checksum")) {
        QString expectedChecksum = data["checksum"].toString();
        QCryptographicHash md5(QCryptographicHash::Md5);
        md5.addData(blockData);
        QString actualChecksum = QString(md5.result().toHex());
        
        if (expectedChecksum != actualChecksum) {
            LOG_ERROR(QString("数据块 #%1 校验和不匹配: 期望=%2, 实际=%3")
                    .arg(blockNumber)
                    .arg(expectedChecksum)
                    .arg(actualChecksum));
            checksumValid = false;
            
            // 发送失败确认消息
            QJsonObject ackObj;
            ackObj["transferId"] = transferId;
            ackObj["blockNumber"] = blockNumber;
            ackObj["success"] = false;
            ackObj["message"] = "校验和不匹配";
            
            sendMessage(socket, MessageType::FileSendAck, ackObj);
            return;
        } else {
            LOG_INFO(QString("数据块 #%1 校验和验证通过").arg(blockNumber));
            checksumValid = true;
        }
    }
    
    // 检查校验和是否有效
    if (!checksumValid) {
        LOG_ERROR(QString("数据块 #%1 校验和验证失败，跳过此块").arg(blockNumber));
        return;
    }
    
    // 如果提供了偏移量，尝试定位文件指针
    if (offset >= 0) {
        LOG_INFO(QString("定位文件指针到偏移量: %1").arg(offset));
        if (!context.file->seek(offset)) {
            LOG_ERROR(QString("调整文件指针失败: %1").arg(context.file->errorString()));
            
            // 尝试重新打开文件并定位
            context.file->close();
            if (context.file->open(QIODevice::ReadWrite) && context.file->seek(offset)) {
                LOG_INFO("重新打开文件并成功定位指针");
            } else {
                LOG_ERROR(QString("重新尝试后仍无法定位文件指针: %1").arg(context.file->errorString()));
                
                // 发送失败确认消息
                QJsonObject ackObj;
                ackObj["transferId"] = transferId;
                ackObj["blockNumber"] = blockNumber;
                ackObj["success"] = false;
                ackObj["message"] = "无法定位文件指针";
                
                sendMessage(socket, MessageType::FileSendAck, ackObj);
                return;
            }
        }
    }
    
    // 写入文件
    qint64 written = context.file->write(blockData);
    if (written != blockData.size()) {
        LOG_ERROR(QString("文件写入错误: %1").arg(context.file->errorString()));
        
        // 检查磁盘空间
        QStorageInfo storage(context.filePath);
        if (storage.isValid() && storage.bytesAvailable() < blockData.size() * 2) {
            LOG_ERROR(QString("磁盘空间不足: 可用 %1 字节").arg(storage.bytesAvailable()));
        }
        
        // 发送失败确认消息
        QJsonObject ackObj;
        ackObj["transferId"] = transferId;
        ackObj["blockNumber"] = blockNumber;
        ackObj["success"] = false;
        ackObj["message"] = "文件写入错误";
        
        sendMessage(socket, MessageType::FileSendAck, ackObj);
        return;
    }
    
    // 确保数据立即写入磁盘
    context.file->flush();
    
    // 更新接收状态
    context.receivedSize = context.file->pos();
    context.lastBlockNumber = blockNumber;
    context.receivedBlocks.insert(blockNumber);
    
    // 记录进度
    if (totalBlocks > 0 && blockNumber % 10 == 0) {
        LOG_INFO(QString("已接收: %1/%2字节 (%3%), 块: %4/%5")
                .arg(context.receivedSize)
                .arg(context.fileSize)
                .arg(context.fileSize > 0 ? int(context.receivedSize * 100 / context.fileSize) : 0)
                .arg(context.receivedBlocks.size())
                .arg(totalBlocks));
    }
    
    // 发送确认消息
    QJsonObject ackObj;
    ackObj["transferId"] = transferId;
    ackObj["blockNumber"] = blockNumber;
    ackObj["success"] = true;
    ackObj["message"] = "接收成功";
    
    // 多次尝试发送确认，确保客户端收到
    bool ackSent = false;
    for (int attempt = 1; attempt <= 2 && !ackSent; attempt++) {
        if (sendMessage(socket, MessageType::FileSendAck, ackObj)) {
            ackSent = true;
        } else {
            LOG_WARNING(QString("发送数据块确认消息失败，尝试 %1/2").arg(attempt));
            QThread::msleep(20); // 减少延迟时间
        }
    }
    
    if (!ackSent) {
        LOG_ERROR(QString("发送数据块 #%1 确认消息失败，已达到最大尝试次数").arg(blockNumber));
    }
}

void Server::handleFileSendFinish(QTcpSocket *socket, const QJsonObject &data)
{
    if (!socket || !fileReceiveMap.contains(socket)) {
        LOG_ERROR("处理文件传输完成消息失败: 无效的socket或未找到对应的文件接收上下文");
        return;
    }
    
    FileReceiveContext &context = fileReceiveMap[socket];
    
    // 获取传输ID并验证
    QString transferId = data.contains("transferId") ? data["transferId"].toString() : 
                        data.contains("clientId") ? data["clientId"].toString() : "";
    
    if (!transferId.isEmpty() && transferId != context.transferId) {
        LOG_WARNING(QString("传输ID不匹配: 期望=%1，收到=%2").arg(context.transferId).arg(transferId));
    }
    
    // 获取文件信息
    qint64 expectedSize = data.contains("fileSize") ? data["fileSize"].toString().toLongLong() : -1;
    int totalBlocks = data.contains("totalBlocks") ? data["totalBlocks"].toInt() : -1;
    QString fileName = data.contains("fileName") ? data["fileName"].toString() : context.fileName;
    QString expectedChecksum = data.contains("checksum") ? data["checksum"].toString() : "";
    
    LOG_INFO(QString("收到文件传输完成消息: 预期大小=%1字节, 总块数=%2, 已接收块数=%3, 已接收大小=%4字节")
            .arg(expectedSize)
            .arg(totalBlocks)
            .arg(context.receivedBlocks.size())
            .arg(context.receivedSize));
    
    // 关闭文件前再次确认所有数据写入
    if (context.file && context.file->isOpen()) {
        context.file->flush(); // 确保数据写入磁盘
        context.file->close();
        LOG_INFO("文件已关闭");
    }
    
    // 记录传输信息
    QDateTime now = QDateTime::currentDateTime();
    qint64 duration = context.startTime.msecsTo(now);
    double speed = 0;
    if (duration > 0) {
        speed = (context.receivedSize * 1000.0) / duration / 1024; // KB/s
    }
    
    LOG_INFO(QString("文件接收完成: [%1] %2, 大小: %3 字节, 用时: %4 秒, 速度: %5 KB/s")
            .arg(transferId)
            .arg(fileName)
            .arg(context.receivedSize)
            .arg(duration / 1000.0)
            .arg(speed));
            
    LOG_INFO(QString("文件保存在: %1").arg(context.filePath));
    
    // 验证文件是否存在和完整性
    QFileInfo fileInfo(context.filePath);
    bool fileOK = false;
    QString errorMsg;
    
    if (fileInfo.exists()) {
        LOG_INFO(QString("文件确认存在，大小为: %1 字节").arg(fileInfo.size()));
        
        // 检查文件权限
        if (!fileInfo.isReadable()) {
            LOG_WARNING("文件不可读");
            errorMsg = "文件不可读";
        }
        // 检查文件大小是否匹配
        else if (expectedSize > 0 && fileInfo.size() != expectedSize) {
            // 计算差异百分比
            double diffPercent = static_cast<double>(qAbs(fileInfo.size() - expectedSize)) / expectedSize * 100.0;
            
            // 如果文件大小差异很小（小于2%或2KB），仍然认为传输成功
            qint64 sizeDiff = qAbs(fileInfo.size() - expectedSize);
            if (sizeDiff < 2048 || diffPercent < 2.0) {
                LOG_INFO(QString("文件大小与预期略有差异，但在可接受范围内: 预期 %1 字节, 实际 %2 字节, 差异 %3 字节 (%4%)")
                      .arg(expectedSize)
                      .arg(fileInfo.size())
                      .arg(sizeDiff)
                      .arg(diffPercent, 0, 'f', 2));
                fileOK = true;
            } else {
                LOG_WARNING(QString("文件大小不匹配: 预期 %1 字节, 实际 %2 字节, 差异 %3 字节 (%4%)")
                      .arg(expectedSize)
                      .arg(fileInfo.size())
                      .arg(sizeDiff)
                      .arg(diffPercent, 0, 'f', 2));
                errorMsg = QString("文件大小不匹配: 预期 %1 字节, 实际 %2 字节")
                      .arg(expectedSize)
                      .arg(fileInfo.size());
                
                // 如果差异不太大（小于10%或10KB），在警告情况下仍接受
                if (sizeDiff < 10240 || diffPercent < 10.0) {
                    LOG_INFO("差异在可容忍范围内，仍然接受文件");
                    fileOK = true;
                }
            }
        }
        // 检查收到的数据块是否符合预期
        else if (totalBlocks > 0 && context.receivedBlocks.size() != totalBlocks) {
            // 计算差异百分比
            double blocksDiffPercent = static_cast<double>(totalBlocks - context.receivedBlocks.size()) / totalBlocks * 100.0;
            
            // 即使数据块数量不匹配，如果文件大小正确，也认为成功
            if (fileInfo.size() == expectedSize || expectedSize <= 0 || blocksDiffPercent < 5.0) {
                LOG_INFO(QString("数据块数量不匹配，但文件大小正确或差异很小: 预期 %1 块, 实际接收 %2 块 (差异 %3%)")
                      .arg(totalBlocks)
                      .arg(context.receivedBlocks.size())
                      .arg(blocksDiffPercent, 0, 'f', 2));
                fileOK = true;
            } else {
                LOG_WARNING(QString("数据块数量不匹配: 预期 %1 块, 实际接收 %2 块 (差异 %3%)")
                      .arg(totalBlocks)
                      .arg(context.receivedBlocks.size())
                      .arg(blocksDiffPercent, 0, 'f', 2));
                errorMsg = QString("数据块数量不匹配: 预期 %1 块, 实际接收 %2 块")
                      .arg(totalBlocks)
                      .arg(context.receivedBlocks.size());
                
                // 如果缺少的块数不太多（小于10%且文件大小接近），仍然接受
                qint64 sizeDiff = expectedSize > 0 ? qAbs(fileInfo.size() - expectedSize) : 0;
                double sizeDiffPercent = expectedSize > 0 ? (static_cast<double>(sizeDiff) / expectedSize * 100.0) : 0.0;
                
                if (blocksDiffPercent < 10.0 && sizeDiffPercent < 5.0) {
                    LOG_INFO("缺少的块数量在可接受范围内，且文件大小接近预期，仍然接受文件");
                    fileOK = true;
                }
            }
        }
        // 如果提供了校验和，则验证文件的完整性
        else if (!expectedChecksum.isEmpty()) {
            // 重新打开文件进行校验
            QFile verifyFile(context.filePath);
            if (verifyFile.open(QIODevice::ReadOnly)) {
                QCryptographicHash md5(QCryptographicHash::Md5);
                
                // 使用缓冲方式读取文件计算校验和，避免一次性加载大文件到内存
                const qint64 bufferSize = 1024 * 1024; // 1MB缓冲区
                QByteArray buffer;
                qint64 totalRead = 0;
                
                LOG_INFO("开始计算文件MD5校验和...");
                
                while (totalRead < fileInfo.size()) {
                    buffer = verifyFile.read(bufferSize);
                    if (buffer.isEmpty()) break;
                    
                    md5.addData(buffer);
                    totalRead += buffer.size();
                    
                    // 显示进度
                    if (totalRead % (10 * bufferSize) == 0) {
                        LOG_INFO(QString("MD5计算进度: %1/%2字节 (%3%)")
                                .arg(totalRead)
                                .arg(fileInfo.size())
                                .arg(int(totalRead * 100 / fileInfo.size())));
                    }
                }
                
                QString actualChecksum = QString(md5.result().toHex());
                verifyFile.close();
                
                LOG_INFO(QString("文件MD5校验和: %1").arg(actualChecksum));
                
                if (actualChecksum != expectedChecksum) {
                    LOG_WARNING(QString("文件校验和不匹配: 期望 %1, 实际 %2")
                              .arg(expectedChecksum)
                              .arg(actualChecksum));
                    errorMsg = "文件校验和不匹配，文件可能已损坏";
                    
                    // 文件大小和块数检查
                    if (fileInfo.size() == expectedSize && context.receivedBlocks.size() == totalBlocks) {
                        LOG_INFO("尽管校验和不匹配，但文件大小和块数都匹配，仍接受文件");
                        fileOK = true;
                    }
                } else {
                    LOG_INFO("文件校验和验证通过，文件完整");
                    fileOK = true;
                }
            } else {
                LOG_ERROR(QString("无法打开文件进行校验: %1").arg(verifyFile.errorString()));
                errorMsg = "无法验证文件完整性";
                
                // 如果其他检查都通过，尽管无法校验，仍然接受文件
                if (fileInfo.size() == expectedSize || (expectedSize > 0 && qAbs(fileInfo.size() - expectedSize) < expectedSize / 50)) {
                    LOG_INFO("无法校验文件，但文件大小符合预期，仍接受文件");
                    fileOK = true;
                }
            }
        } else {
            // 如果没有提供校验和，但其他检查都通过，则认为文件完整
            LOG_INFO("文件大小与预期一致，认为文件完整");
            fileOK = true;
        }
    } else {
        LOG_ERROR(QString("文件验证失败，文件不存在: %1").arg(context.filePath));
        errorMsg = "文件不存在";
        
        // 尝试查找文件
        QDir searchDir(QFileInfo(context.filePath).dir());
        QStringList files = searchDir.entryList(QDir::Files);
        if (!files.isEmpty()) {
            LOG_INFO(QString("目录中存在其他文件:"));
            for (const QString &file : files) {
                LOG_INFO(QString(" - %1").arg(file));
            }
            
            // 检查是否有类似名称的文件
            for (const QString &file : files) {
                if (file.contains(fileName) || fileName.contains(file)) {
                    LOG_INFO(QString("找到可能的匹配文件: %1").arg(file));
                    QString possiblePath = searchDir.absoluteFilePath(file);
                    QFileInfo possibleFile(possiblePath);
                    
                    if (possibleFile.size() == expectedSize || 
                        (expectedSize > 0 && qAbs(possibleFile.size() - expectedSize) < expectedSize / 50)) {
                        LOG_INFO(QString("找到的文件大小与预期一致，尝试使用此文件"));
                        context.filePath = possiblePath;
                        context.fileName = file;
                        fileOK = true;
                        break;
                    }
                }
            }
        } else {
            LOG_WARNING("目录中没有任何文件");
        }
    }
    
    // 发送确认消息回客户端
    QJsonObject response;
    response["success"] = fileOK;
    response["transferId"] = transferId;
    response["fileName"] = fileName;
    response["message"] = fileOK ? 
                        QString("文件 %1 接收完成").arg(fileName) : 
                        QString("文件 %1 接收失败: %2").arg(fileName).arg(errorMsg);
    response["path"] = context.filePath;
    response["receivedSize"] = QString::number(context.receivedSize);
    response["expectedSize"] = QString::number(context.fileSize);
    response["receivedBlocks"] = context.receivedBlocks.size();
    response["totalBlocks"] = totalBlocks;
    
    LOG_INFO("发送文件接收完成确认消息");
    
    // 多次尝试发送确认消息，确保客户端收到
    bool confirmSent = false;
    for (int attempt = 1; attempt <= 3 && !confirmSent; attempt++) {
        if (sendMessage(socket, MessageType::FileSendFinish, response)) {
            confirmSent = true;
            LOG_INFO(QString("文件接收完成确认消息已发送 (尝试 %1/3)").arg(attempt));
        } else {
            LOG_WARNING(QString("发送文件接收完成确认消息失败，尝试 %1/3").arg(attempt));
            QThread::msleep(100); // 减少重试等待时间
        }
    }
    
    if (!confirmSent) {
        LOG_ERROR("发送文件接收完成确认消息失败，已达到最大尝试次数");
    }
    
    // 如果文件不完整，尝试删除
    if (!fileOK && fileInfo.exists()) {
        LOG_WARNING(QString("文件接收不完整，尝试删除: %1").arg(context.filePath));
        if (QFile::remove(context.filePath)) {
            LOG_INFO("已删除不完整文件");
        } else {
            LOG_ERROR("删除不完整文件失败");
        }
    }
    
    // 从映射中移除
    fileReceiveMap.remove(socket);
    
    // 恢复客户端的屏幕更新
    if (clients.contains(socket) && !clients[socket].receivingScreenUpdates) {
        LOG_INFO("文件传输完成，恢复客户端的屏幕更新");
        startClientScreenUpdates(socket, 10); // 使用默认10 FPS
    }
}